/**
 * DESC: Tests ellipse drawing using Bresenham algorithm.
 *
 * IMP: HIGH
 */

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>

#include <object.h>
#include <ellipse.h>
#include <surface.h>
#include <visual.h>

#include <debug.h>
#include <unittest.h>


int main( int argc, char *argv[] )
{
  debug_level = 0; /* 1 = warn, 2 = info, 3 = verbose, 4 = debug mode */

  printf( "Bresenham drawing test.\n" );
  printf( "Press any key to go next test step.\n" );


  visual_init( 800, 600 );

  ellipse_draw_aliased = ellipse_draw_bresenham;

  coord_t p = { 0, 0 };
  surface_t *s = surface_new( 800, 600 );
  assert_not_null( s );

  ellipse_t *o = ellipse_new();
  assert_not_null( o );

  color_t c;
  COLOR_FROM_ARGB( c, COLOR_RED );
  object_init3( o, c, 0.5 );

  printf( "100px red ellipse at ( 100, 100 )\n" );
  COLOR_FROM_ARGB( OBJECT_COLOR( o ), COLOR_RED );

  SET_COORD( o->center, 100, 100 );
  o->radiusx = 100;
  o->radiusy = 50;
  OBJECT_UNSET_DRAW_OPT( o, DRAW_FILL );
  object_draw( o, s );

  SET_COORD( o->center, 400, 400 );
  o->radiusx = 60;
  o->radiusy = 134;
  OBJECT_SET_DRAW_OPT( o, DRAW_FILL );
  object_draw( o, s );

  SET_COORD( o->center, 350, 100 );
  o->radiusx = 100;
  o->radiusy = 30;
  OBJECT_SET_DRAW_OPT( o, DRAW_FILL );
  object_draw( o, s );

  visual_display( s, p );
  visual_update();
  visual_waitkey();

  surface_clear( s );

  COLOR_FROM_ARGB( OBJECT_COLOR( o ), COLOR_GREEN );

  SET_COORD( o->center, 100, 100 );
  o->radiusx = 101;
  o->radiusy = 51;
  OBJECT_SET_DRAW_OPT( o, DRAW_FILL );
  object_draw( o, s );

  SET_COORD( o->center, 400, 400 );
  o->radiusx = 61;
  o->radiusy = 135;
  OBJECT_UNSET_DRAW_OPT( o, DRAW_FILL );
  object_draw( o, s );


  SET_COORD( o->center, 350, 100 );
  o->radiusx = 101;
  o->radiusy = 31;
  OBJECT_UNSET_DRAW_OPT( o, DRAW_FILL );
  object_draw( o, s );

  visual_display( s, p );
  visual_update();
  visual_waitkey();

  surface_clear( s );

  COLOR_FROM_ARGB( OBJECT_COLOR( o ), COLOR_RED );

  SET_COORD( o->center, 100, 50 );
  o->radiusx = 101;
  o->radiusy = 51;
  OBJECT_UNSET_DRAW_OPT( o, DRAW_FILL );
  object_draw( o, s );

  COLOR_FROM_ARGB( OBJECT_COLOR( o ), COLOR_MAGENTA );

  SET_COORD( o->center, 400, 100 );
  o->radiusx = 101;
  o->radiusy = 51;
  OBJECT_UNSET_DRAW_OPT( o, DRAW_FILL );
  object_draw( o, s );

  SET_COORD( o->center, 650, 100 );
  o->radiusx = 101;
  o->radiusy = 51;
  OBJECT_SET_DRAW_OPT( o, DRAW_FILL );
  object_draw( o, s );

  COLOR_FROM_ARGB( OBJECT_COLOR( o ), COLOR_CYAN );

  SET_COORD( o->center, 400, 300 );
  o->radiusx = 51;
  o->radiusy = 101;
  OBJECT_UNSET_DRAW_OPT( o, DRAW_FILL );
  object_draw( o, s );

  SET_COORD( o->center, 650, 300 );
  o->radiusx = 51;
  o->radiusy = 101;
  OBJECT_SET_DRAW_OPT( o, DRAW_FILL );
  object_draw( o, s );

  visual_display( s, p );
  visual_update();
  visual_waitkey();

  surface_clear( s );


  unsigned r;
  SET_COORD( o->center, 400, 300 );
  o->radiusx = 300;
  for ( r=0; r <= 300; r += 10 )
    {
      o->radiusy = r;
      OBJECT_UNSET_DRAW_OPT( o, DRAW_FILL );
      object_draw( o, s );
    }

  visual_display( s, p );
  visual_update();
  visual_waitkey();

  surface_clear( s );

  SET_COORD( o->center, 400, 300 );
  o->radiusx = 200;
  for ( r=0; r <= 400; r += 10 )
    {
      o->radiusx = r;
      OBJECT_UNSET_DRAW_OPT( o, DRAW_FILL );
      object_draw( o, s );
    }

  visual_display( s, p );
  visual_update();
  visual_waitkey();

  surface_clear( s );

  surface_free( s );
  object_free( o );

  visual_quit();

  return ask_user_yn( "Everything rendered as expect?" ) != 1;
}
